package com.ruoyi.web.controller.tool.designpattern.creationalPatterns.prototype;

/**
 * 原型模式
 *
 * @author Hack2003
 * @date 2024/3/21 11:09
 **/
// 1. 定义一个实现了Cloneable接口的原型类
 class Shape implements Cloneable {
    private String type;

    public Shape(String type) {
        this.type = type;
    }

    // 原型对象的核心方法：克隆自身
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return (Shape) super.clone();
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

// 2. 创建一个具体的原型类继承自原型基类
 class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        super("Circle");
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    // 覆写父类的clone方法以提供深度克隆支持
    @Override
    public Circle clone() throws CloneNotSupportedException {
        Circle clonedCircle = (Circle) super.clone();
        return clonedCircle;
    }
}

/**
 * 原型模式（Prototype Pattern）是一种创建型设计模式，
 * 它允许通过复制现有对象来创建新对象，
 * 而不是每次都从头开始创建新的实例。
 * 在Java中，我们通常会利用Cloneable接口和Object类的clone()方法实现原型模式。
 */
public class Test {
    public static void main(String[] args) {
        try {
            // 创建一个原始圆对象
            Circle originalCircle = new Circle(5);

            // 使用原型模式克隆出一个新的圆对象
            Circle clonedCircle = (Circle) originalCircle.clone();

            System.out.println("原始圆半径: " + originalCircle.getRadius());
            System.out.println("克隆圆半径: " + clonedCircle.getRadius());

            // 改变原对象的属性值，查看克隆对象是否受影响
            originalCircle.setRadius(10);
            System.out.println("\n更后原始圆半径:");
            System.out.println("原始圆半径: " + originalCircle.getRadius());
            System.out.println("克隆圆半径: " + clonedCircle.getRadius());  // 应该保持不变

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
